package org.springblade.flow.repair.parts.listener;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.sida.voice.service.VoiceTemplate;
import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.api.delegate.Expression;
import org.flowable.engine.ProcessEngine;
import org.flowable.engine.ProcessEngines;
import org.flowable.engine.TaskService;
import org.flowable.engine.delegate.TaskListener;
import org.flowable.engine.task.Comment;
import org.flowable.task.service.delegate.BaseTaskListener;
import org.flowable.task.service.delegate.DelegateTask;
import org.springblade.common.cache.UserCache;
import org.springblade.common.constant.BaseRoleConstant;
import org.springblade.common.constant.MaintenanceSmsConstant;
import org.springblade.common.constant.TemplateMsgConstant;
import org.springblade.common.constant.VoiceConstant;
import org.springblade.core.tool.constant.BladeConstant;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.SpringUtil;
import org.springblade.flow.core.constant.ProcessConstant;
import org.springblade.flow.core.utils.TaskUtil;
import org.springblade.flow.repair.parts.constant.PartsProcessConstant;
import org.springblade.flow.repair.parts.vo.ProcessTaskVO;
import org.springblade.modules.admin.entity.MaintainMsg;
import org.springblade.modules.admin.enums.MsgTypeEnum;
import org.springblade.modules.admin.enums.TaskStatusEnum;
import org.springblade.modules.admin.service.MaintainMsgService;
import org.springblade.modules.admin.service.MaintainPartsWorkService;
import org.springblade.modules.admin.service.WeChatDialogueService;
import org.springblade.modules.admin.utils.AsyncUtils;
import org.springblade.modules.admin.vo.PartsSimpleInfoVO;
import org.springblade.modules.resource.utils.SmsUtil;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.service.IUserService;
import org.springblade.modules.system.vo.SimpleUserVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 更换配件任务监听器
 * @author ysq
 * @date 2022/06/29
 */
@Slf4j
@Component
public class PartsTaskListener implements TaskListener {

	private Expression status;

	@Override
	public void notify(DelegateTask delegateTask) {
		AsyncUtils asyncUtils = SpringUtil.getBean(AsyncUtils.class);
		MaintainPartsWorkService businessService = SpringUtil.getBean(MaintainPartsWorkService.class);
		IUserService userService = SpringUtil.getBean(IUserService.class);
		MaintainMsgService msgService = SpringUtil.getBean(MaintainMsgService.class);
		PartsSimpleInfoVO partsSimpleInfo = businessService.getPartsSimpleInfo(delegateTask.getProcessInstanceId());
		switch (delegateTask.getEventName()) {
			case BaseTaskListener.EVENTNAME_ASSIGNMENT: {
				log.info(">>>>>>>>>任务分配人完成事件监听,发送相关消息通知：{}>>>>>>>>>", delegateTask.getProcessInstanceId());
				SimpleUserVO approveUserInfo = userService.getSimpleUserInfo(TaskUtil.getUserId(delegateTask.getAssignee()));
				String taskKey = delegateTask.getTaskDefinitionKey();
				switch (taskKey) {
					case PartsProcessConstant.WAREHOUSE_TASK:{
						log.info("===========发送发货审批web消息,审批人:[{}]===========", approveUserInfo.getUserName());
						MaintainMsg maintainMsg = new MaintainMsg();
						maintainMsg.setTitle(String.format("%s-%s", partsSimpleInfo.getBuildingName(), partsSimpleInfo.getElevatorAddress()));
						maintainMsg.setContent("您有一个【配件发货】的审批");
						maintainMsg.setType(MsgTypeEnum.ELEVATOR_PARTS_SHIPMENTS.getId());
						maintainMsg.setOtherId(partsSimpleInfo.getId());
						msgService.sendMsg(maintainMsg, Arrays.asList(approveUserInfo.getUserId()));

						log.info("===========发送发货审批短信,审批人:[{}], 手机号码:[{}]===========", approveUserInfo.getUserName(), approveUserInfo.getPhone());
						Map<String, String> smsParam = new HashMap<>(2);
						smsParam.put("location", partsSimpleInfo.getBuildingName() + partsSimpleInfo.getElevatorAddress());
						smsParam.put("type", "待发货");
						smsParam.put("module", "梯无忧后台配件发货");
						//SmsUtil.sendMessage(MaintenanceSmsConstant.MAINTAIN_AUDIT, BladeConstant.ADMIN_TENANT_ID, smsParam, approveUserInfo.getPhone());
						SmsUtil.sendMessage(MaintenanceSmsConstant.PARTS_MESSAGE, BladeConstant.ADMIN_TENANT_ID, smsParam, approveUserInfo.getPhone());


						//2023-08-31新增电话
						log.info("===========给维修人打电话,审批人:[{}], 手机号码:[{}]===========", approveUserInfo.getUserName(), approveUserInfo.getPhone());
						Map<String, String> phoneMap = new HashMap<>(2);
						phoneMap.put("place", partsSimpleInfo.getBuildingName() + partsSimpleInfo.getElevatorAddress());
						phoneMap.put("location", "梯无忧后台配件发货");
						VoiceTemplate voiceTemplate = new VoiceTemplate();
						voiceTemplate.setTemplateCode(VoiceConstant.PARTS_MESSAGE);
						voiceTemplate.setTemplateParam(phoneMap);
						voiceTemplate.setPhoneNumber(approveUserInfo.getPhone());
						asyncUtils.sendPhone(voiceTemplate);
						break;
					}
					default:break;
				}
				break;
			}
			case BaseTaskListener.EVENTNAME_COMPLETE: {
				log.info(">>>>>>>>>任务完成事件监听 {}>>>>>>>>>", delegateTask.getProcessInstanceId());
				ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
				TaskService taskService = processEngine.getTaskService();
				// 可获取节点表单
				Map<String, Object> variables = taskService.getVariables(delegateTask.getId());
				ProcessTaskVO processTaskVO = new ProcessTaskVO();
				processTaskVO.setProcessDefinitionId(delegateTask.getProcessDefinitionId());
				processTaskVO.setProcessInstanceId(delegateTask.getProcessInstanceId());
				processTaskVO.setEventName(delegateTask.getEventName());
				processTaskVO.setAssignee(TaskUtil.getUserId(delegateTask.getAssignee()));
				processTaskVO.setComment(variables.get("comment").toString());
				User user = UserCache.getUser(TaskUtil.getUserId(delegateTask.getAssignee()));
				if (user != null) {
					processTaskVO.setAssigneeName(user.getRealName());
				}
				if (Boolean.valueOf(String.valueOf(variables.get("pass")))) {  // 通过
					// 更新工单状态
					processTaskVO.setStatus(String.valueOf(status.getValue(delegateTask)));
					businessService.updatePartsWorkStatus(processTaskVO);
					// 发送任务调度消息
					String taskKey = delegateTask.getTaskDefinitionKey();
					if (PartsProcessConstant.WAREHOUSE_TASK.equals(taskKey)) {
						List<Long> userIds = userService.getUserByRoleName(BaseRoleConstant.DISPATCHERS);
						for (Long userId : userIds) {
							SimpleUserVO approveUserInfo = userService.getSimpleUserInfo(userId);
							log.info("===========发送配件任务调度web消息,调度人:[{}]===========", approveUserInfo.getUserName());
							MaintainMsg maintainMsg = new MaintainMsg();
							maintainMsg.setTitle(String.format("%s-%s", partsSimpleInfo.getBuildingName(), partsSimpleInfo.getElevatorAddress()));
							maintainMsg.setContent("您有一个【配件任务】需要调度");
							maintainMsg.setType(MsgTypeEnum.ELEVATOR_PARTS_DISPATCHERS.getId());
							maintainMsg.setOtherId(partsSimpleInfo.getId());
							msgService.sendMsg(maintainMsg, Arrays.asList(approveUserInfo.getUserId()));

							log.info("===========发送配件任务调度短信,调度人:[{}], 手机号码:[{}]===========", approveUserInfo.getUserName(), approveUserInfo.getPhone());
							Map<String, String> smsParam = new HashMap<>(2);
							smsParam.put("location", partsSimpleInfo.getBuildingName() + partsSimpleInfo.getElevatorAddress());
							smsParam.put("type", "待调度");
							smsParam.put("module", "梯无忧后台配件调度");
							//SmsUtil.sendMessage(MaintenanceSmsConstant.MAINTAIN_AUDIT, BladeConstant.ADMIN_TENANT_ID, smsParam, approveUserInfo.getPhone());
							SmsUtil.sendMessage(MaintenanceSmsConstant.PARTS_MESSAGE, BladeConstant.ADMIN_TENANT_ID, smsParam, approveUserInfo.getPhone());


							Map<String, String> phoneMap = new HashMap<>(2);
							phoneMap.put("place", partsSimpleInfo.getBuildingName() + partsSimpleInfo.getElevatorAddress());
							phoneMap.put("location", "梯无忧后台配件调度");
							VoiceTemplate voiceTemplate = new VoiceTemplate();
							voiceTemplate.setTemplateCode(VoiceConstant.PARTS_MESSAGE);
							voiceTemplate.setTemplateParam(phoneMap);
							voiceTemplate.setPhoneNumber(approveUserInfo.getPhone());
							asyncUtils.sendPhone(voiceTemplate);
						}
					}
				} else {  // 不通过
					// 更新工单状态
					processTaskVO.setStatus(String.valueOf(TaskStatusEnum.PARTS_CLOSE.getStatus()));
					businessService.updatePartsWorkStatus(processTaskVO);
					// 申请人信息
					Long applyUser = Long.valueOf(String.valueOf(variables.get(ProcessConstant.TASK_VARIABLE_CREATE_USER_ID)));
					SimpleUserVO applyUserInfo = userService.getSimpleUserInfo(applyUser);
					if (Func.isNotEmpty(applyUserInfo.getOpenid())) {
						WeChatDialogueService weChatDialogueService = SpringUtil.getBean(WeChatDialogueService.class);
						// 工单id
						Long businessId = Long.valueOf(String.valueOf(variables.get(ProcessConstant.BUSINESS_ID)));
						// 跳转链接
						String skipUrl = String.format("pages/approve/partApprovalDetail?id=%s", businessId);
						Map<String, String> templateDataMap = new HashMap<>(8);
						templateDataMap.put("first","您的配件申请已审批");
						templateDataMap.put("keyword1", "审批不通过");
						templateDataMap.put("keyword2", user == null ? null : user.getRealName());
						templateDataMap.put("keyword3", DateUtil.format(delegateTask.getCreateTime(), DatePattern.NORM_DATETIME_PATTERN));
						List<Comment> comments = taskService.getTaskComments(delegateTask.getId(), ProcessConstant.TYPE_COMMENT);
						templateDataMap.put("remark", comments.size() > 0 ? comments.get(0).getFullMessage() : null);
						templateDataMap.put("params",skipUrl);
						log.info("===========发送审批结果模板消息,申请人:[{}]===========", applyUserInfo.getUserName());
						weChatDialogueService.sendMsg(applyUserInfo.getOpenid(), TemplateMsgConstant.T_APPROVE_RESULT_ID, templateDataMap);
					}
					log.info("===========发送审批结果短信,申请人:[{}], 手机号码:[{}]===========", applyUserInfo.getUserName(), applyUserInfo.getPhone());
					Map<String, String> smsParam = new HashMap<>(2);
					smsParam.put("auditType", "审核不通过");
					SmsUtil.sendMessage(MaintenanceSmsConstant.AUDIT_FAILED, BladeConstant.ADMIN_TENANT_ID, smsParam, applyUserInfo.getPhone());
				}
				break;
			}
			default:
				break;
		}
	}

}
